--- @param extension Package
--- @param HY HY_Utility
--- @param U Utility
return function(extension, HY, U)
    local hy_murasa_minamitsu = General:new(extension, "hy_murasa_minamitsu", "jin_k", 4, 4, General.Female)
    local sink_whirlpool = fk.CreateSkill {
        name = "sink_whirlpool",
    }
    sink_whirlpool:addEffect("active", {
        can_use = function (self, player)
            if player.phase ~= Player.Play then
                return false
            end
            local mark = player:getTableMark("sink_whirlpool")
            return not table.every(Fk:currentRoom().alive_players, function(t)
                return table.contains(mark, t.id)
            end)
        end,
        target_num = 1,
        target_filter = function(self, player, to_select, selected, selected_cards)
            local mark = player:getTableMark("sink_whirlpool")
            return not table.contains(mark, to_select.id) and #selected == 0 and #to_select:getCardIds("hej") > 0
        end,
        card_filter = Util.FalseFunc,
        prompt = function(self, selected_cards, selected_targets)
            return "sink_whirlpool_prompt"
        end,
        on_use = function(self, room, cardUseEvent)
            local player = cardUseEvent.from
            local target = cardUseEvent.tos[1]
            local cardId = room:askToChooseCard(player, {
                target = target,
                flag = "hej",
                skill_name = sink_whirlpool.name
            })
            local isHand = table.contains(target:getCardIds("h"), cardId)
            room:recastCard({ cardId }, target, sink_whirlpool.name)
            if not isHand then
                room:damage({
                    to = player,
                    damage = 1,
                    damageType = fk.NormalDamage,
                    skillName = sink_whirlpool.name,
                })
            end
            local mark = player:getTableMark("sink_whirlpool")
            table.insert(mark, target.id)
            room:setPlayerMark(player, "sink_whirlpool", mark)
        end,
    })
    sink_whirlpool:addEffect(fk.EventPhaseStart, {
        can_refresh = function(self, event, target, player, data)
            return player:hasSkill(sink_whirlpool.name) and player == target and player.phase == Player.Play
        end,
        on_refresh = function(self, event, target, player, data)
            player.room:setPlayerMark(player, "sink_whirlpool", 0)
        end,
    })
    local flood_disaster = fk.CreateSkill {
        name = "flood_disaster",
    }
    flood_disaster:addEffect(fk.Damaged, {
        anim_type = "control",
        can_trigger = function(self, event, target, player, data)
            return player:hasSkill(flood_disaster.name) and player == target and table.find(player.room:getOtherPlayers(player), function(t)
                return #t:getCardIds("he") > 0
            end)
        end,
        on_trigger = function(self, event, target, player, data)
            event:setSkillData(self, "cancel_cost", false)
            for i = 1, data.damage do
                if event:getSkillData(self, "cancel_cost") then break end
                self:doCost(event, target, player, data)
            end
        end,
        on_cost = function(self, event, target, player, data)
            local room = player.room
            event:setCostData(self, table.map(room:askToChoosePlayers(player, {
                targets = table.filter(room:getOtherPlayers(player), function(t)
                    return #t:getCardIds("he") > 0
                end),
                min_num = 1,
                max_num = 1,
                skill_name = flood_disaster.name,
                prompt = "flood_disaster_prompt"
            }), Util.IdMapper))
            if #event:getCostData(self) > 0 then
                return true
            end
            event:setSkillData(self, "cancel_cost", true)
        end,
        on_use = function(self, event, target, player, data)
            local room = player.room
            local skillTarget = room:getPlayerById(event:getCostData(self)[1])
            local cardId = table.random(skillTarget:getCardIds("he"), 1)
            player:addToPile("anchor", cardId, true, flood_disaster.name)
        end,
    })
    local start_voyage = fk.CreateSkill {
        name = "start_voyage",
    }
    start_voyage:addEffect("active", {
        anim_type = "offensive",
        target_num = 1,
        target_filter = function(self, player, to_select, selected, selected_cards)
            return to_select ~= player and not player:isProhibited(to_select, Fk:cloneCard("slash"))
        end,
        card_filter = Util.FalseFunc,
        can_use = function(self, player)
            if #player:getPile("anchor") == 0 then
                return false
            end
            return player:hasSkill(start_voyage.name) and player:usedSkillTimes(start_voyage.name, Player.HistoryPhase) < 1 and not player:prohibitUse(Fk:cloneCard("slash")) and player:canUse(Fk:cloneCard("slash"))
        end,
        prompt = function(self, selected, selected_cards)
            return "start_voyage_prompt"
        end,
        on_use = function(self, room, cardUseEvent)
            local player = cardUseEvent.from
            local card = Fk:cloneCard("slash")
            card:addSubcards(player:getPile("anchor"))
            table.insertIfNeed(card.skillNames, start_voyage.name)
            room:useCard({
                from = cardUseEvent.from,
                tos = cardUseEvent.tos,
                card = card,
                additionalDamage = #card.subcards >= 3 and 1 or 0
            })
        end
    })
    start_voyage:addEffect(fk.TargetSpecified, {
        can_refresh = function(self, event, target, player, data)
            return player:hasSkill(start_voyage.name) and target == player and data.card and table.contains(data.card.skillNames, "start_voyage") and data.card.trueName == "slash"
        end,
        on_refresh = function(self, event, target, player, data)
            data:setResponseTimes(data:getResponseTimes(data.to) + 1, data.to)
        end,
    })
    start_voyage:addEffect(fk.Damage, {
        can_refresh = function(self, event, target, player, data)
            return player:hasSkill(start_voyage.name) and target == player and data.card and table.contains(data.card.skillNames, "start_voyage") and data.card.trueName == "slash"
        end,
        on_refresh = function(self, event, target, player, data)
            local room = player.room
            if #data.card.subcards >= 2 and #data.to:getCardIds("he") > 0 then
                if room:askToSkillInvoke(player, {
                        skill_name = "start_voyage",
                        prompt = "start_voyage_prompt_prey::" .. data.to.id
                    }) then
                    local cardId = room:askToChooseCard(player, {
                        target = data.to,
                        flag = "he",
                        skill_name = "start_voyage"
                    })
                    room:moveCardTo(cardId, Card.PlayerSpecial, player, fk.ReasonJustMove, "start_voyage", "anchor", true, player)
                end
            end
        end,
    })
    extension:loadSkillSkels { sink_whirlpool, flood_disaster, start_voyage }
    hy_murasa_minamitsu:addSkill("sink_whirlpool")
    hy_murasa_minamitsu:addSkill("flood_disaster")
    hy_murasa_minamitsu:addSkill("start_voyage")
    Fk:loadTranslationTable {
        ["hy_murasa_minamitsu"] = "村纱水蜜",
        ["#hy_murasa_minamitsu"] = "水底航行者",
        ["illustrator:hy_murasa_minamitsu"] = "ふなむし のもれ",
        ["designer:hy_murasa_minamitsu"] = "黑曜人形",
        ["cv:hy_murasa_minamitsu"] = "",

        ["sink_whirlpool"] = "溺涡",
        [":sink_whirlpool"] = "出牌阶段每角色限一次，你可以重铸一名角色区域内一张牌，若不为手牌，你受到1点伤害。",
        ["sink_whirlpool_prompt"] = "溺涡：你可以重铸一名角色区域内一张牌，若不为手牌会受到伤害",
        ["flood_disaster"] = "水难",
        [":flood_disaster"] = "在你受到1点伤害后，你可以将一名其他角色的随机一张牌置于你的武将牌上，称为“锚”。",
        ["anchor"] = "锚",
        ["flood_disaster_prompt"] = "水难：你可以将其他角色的牌作为“锚”置于你的武将牌上。",

        ["start_voyage"] = "出航",
        [":start_voyage"] = "出牌阶段限一次，你可以将所有“锚”当作无距离限制的【杀】使用，此【杀】需要额外一张【闪】才能抵消，若你以此法失去的“锚”数：不小于2，此【杀】造成伤害后你可以将目标一张牌作为“锚”置于武将牌上；不小于3，此【杀】伤害+1。",
        ["start_voyage_prompt"] = "出航：你可以将所有“锚”当作无距离限制的【杀】使用",
        ["start_voyage_prompt_prey"] = "出航：你可以获得%dest一张牌作为“锚”",
    }
end
